import os
from dotenv import load_dotenv

load_dotenv()

BOT_TOKEN = os.getenv('BOT_TOKEN')
OWNER_ID = int(os.getenv('OWNER_ID', 0))
OWNER_USERNAME = os.getenv('OWNER_USERNAME', '')

# لول‌های دسترسی
ACCESS_LEVELS = {
    'owner': 100,
    'super_admin': 80,
    'admin': 50,
    'moderator': 30,
    'user': 10
}

# پلن‌های اشتراک
PLANS = {
    '1month': {'name': 'یک ماهه', 'price': 100000, 'days': 30, 'traffic': '50GB'},
    '2month': {'name': 'دو ماهه', 'price': 180000, 'days': 60, 'traffic': '120GB'},
    '3month': {'name': 'سه ماهه', 'price': 250000, 'days': 90, 'traffic': '200GB'},
    '6month': {'name': 'شش ماهه', 'price': 450000, 'days': 180, 'traffic': '500GB'},
    '1year': {'name': 'یک ساله', 'price': 800000, 'days': 365, 'traffic': 'نامحدود'}
}

# تنظیمات پرداخت
CARD_NUMBER = os.getenv('CARD_NUMBER', '6037-9975-1234-5678')
CARD_HOLDER = os.getenv('CARD_HOLDER', 'نام صاحب کارت')

# تنظیمات ریپورت
MIN_WITHDRAW = 100000
COMMISSION_PERCENT = 20
REFERRAL_BONUS = 5000  # هدیه ثبت‌نام به معرف
import sqlite3
from datetime import datetime, timedelta
import json
from config import PLANS, COMMISSION_PERCENT

class Database:
    def __init__(self):
        self.conn = sqlite3.connect('reporter_bot.db', check_same_thread=False)
        self.conn.row_factory = sqlite3.Row
        self.cursor = self.conn.cursor()
        self.setup()
    
    def setup(self):
        # کاربران
        self.cursor.execute('''
            CREATE TABLE IF NOT EXISTS users (
                user_id INTEGER PRIMARY KEY,
                username TEXT,
                first_name TEXT,
                phone TEXT,
                balance INTEGER DEFAULT 0,
                joined_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                referral_by INTEGER,
                subscription_until TIMESTAMP,
                total_referrals INTEGER DEFAULT 0,
                referral_earnings INTEGER DEFAULT 0,
                access_level INTEGER DEFAULT 10,
                is_banned INTEGER DEFAULT 0,
                ban_reason TEXT,
                total_purchases INTEGER DEFAULT 0
            )
        ''')
        
        # پرسنل
        self.cursor.execute('''
            CREATE TABLE IF NOT EXISTS staff (
                user_id INTEGER PRIMARY KEY,
                username TEXT,
                full_name TEXT,
                role TEXT,
                access_level INTEGER,
                added_by INTEGER,
                added_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                permissions TEXT DEFAULT '{}',
                is_active INTEGER DEFAULT 1
            )
        ''')
        
        # کانال‌ها و گروه‌ها
        self.cursor.execute('''
            CREATE TABLE IF NOT EXISTS channels (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                channel_id TEXT UNIQUE,
                channel_name TEXT,
                type TEXT,
                added_by INTEGER,
                added_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                is_required INTEGER DEFAULT 0,
                member_count INTEGER DEFAULT 0
            )
        ''')
        
        # زیرمجموعه‌ها
        self.cursor.execute('''
            CREATE TABLE IF NOT EXISTS referrals (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                inviter_id INTEGER,
                invited_id INTEGER,
                date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                commission_paid INTEGER DEFAULT 0
            )
        ''')
        
        # تراکنش‌ها
        self.cursor.execute('''
            CREATE TABLE IF NOT EXISTS transactions (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                user_id INTEGER,
                amount INTEGER,
                type TEXT,
                status TEXT DEFAULT 'pending',
                date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                plan TEXT,
                confirmed_by INTEGER,
                receipt_file TEXT
            )
        ''')
        
        # لاگ فعالیت‌ها
        self.cursor.execute('''
            CREATE TABLE IF NOT EXISTS activity_logs (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                user_id INTEGER,
                username TEXT,
                action TEXT,
                details TEXT,
                timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        ''')
        
        # گزارش‌ها
        self.cursor.execute('''
            CREATE TABLE IF NOT EXISTS reports (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                reporter_id INTEGER,
                target_type TEXT,
                target_id TEXT,
                reason TEXT,
                status TEXT DEFAULT 'pending',
                created_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                resolved_by INTEGER,
                resolved_date TIMESTAMP
            )
        ''')
        
        # تنظیمات
        self.cursor.execute('''
            CREATE TABLE IF NOT EXISTS settings (
                key TEXT PRIMARY KEY,
                value TEXT
            )
        ''')
        
        # درخواست‌های برداشت
        self.cursor.execute('''
            CREATE TABLE IF NOT EXISTS withdrawals (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                user_id INTEGER,
                amount INTEGER,
                card_number TEXT,
                status TEXT DEFAULT 'pending',
                request_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                processed_date TIMESTAMP,
                processed_by INTEGER
            )
        ''')
        
        self.conn.commit()
        self._insert_defaults()
    
    def _insert_defaults(self):
        # تنظیمات پیش‌فرض
        defaults = {
            'min_withdraw': '100000',
            'commission_percent': '20',
            'referral_bonus': '5000',
            'support_username': '@support',
            'bot_version': '2.0'
        }
        for key, value in defaults.items():
            self.cursor.execute('INSERT OR IGNORE INTO settings (key, value) VALUES (?, ?)', (key, value))
        self.conn.commit()
    
    # === متدهای کاربران ===
    def add_user(self, user_id, username, first_name, phone=None, referral_by=None):
        self.cursor.execute('''
            INSERT OR IGNORE INTO users (user_id, username, first_name, phone, referral_by)
            VALUES (?, ?, ?, ?, ?)
        ''', (user_id, username, first_name, phone, referral_by))
        
        if referral_by and referral_by != user_id:
            self.cursor.execute('SELECT id FROM referrals WHERE inviter_id = ? AND invited_id = ?', 
                              (referral_by, user_id))
            if not self.cursor.fetchone():
                self.cursor.execute('INSERT INTO referrals (inviter_id, invited_id) VALUES (?, ?)',
                                  (referral_by, user_id))
                self.cursor.execute('UPDATE users SET total_referrals = total_referrals + 1 WHERE user_id = ?',
                                  (referral_by,))
                # هدیه ثبت‌نام
                bonus = int(self.get_setting('referral_bonus', 5000))
                self.cursor.execute('UPDATE users SET referral_earnings = referral_earnings + ? WHERE user_id = ?',
                                  (bonus, referral_by))
        
        self.conn.commit()
    
    def get_user(self, user_id):
        self.cursor.execute('SELECT * FROM users WHERE user_id = ?', (user_id,))
        return self.cursor.fetchone()
    
    def get_setting(self, key, default=None):
        self.cursor.execute('SELECT value FROM settings WHERE key = ?', (key,))
        result = self.cursor.fetchone()
        return result['value'] if result else default
    
    # === متدهای پرسنل ===
    def add_staff(self, user_id, username, full_name, role, access_level, added_by, permissions=None):
        if permissions is None:
            permissions = {}
        self.cursor.execute('''
            INSERT OR REPLACE INTO staff (user_id, username, full_name, role, access_level, added_by, permissions)
            VALUES (?, ?, ?, ?, ?, ?, ?)
        ''', (user_id, username, full_name, role, access_level, added_by, json.dumps(permissions)))
        self.cursor.execute('UPDATE users SET access_level = ? WHERE user_id = ?', (access_level, user_id))
        self.conn.commit()
    
    def remove_staff(self, user_id):
        self.cursor.execute('DELETE FROM staff WHERE user_id = ?', (user_id,))
        self.cursor.execute('UPDATE users SET access_level = 10 WHERE user_id = ?', (user_id,))
        self.conn.commit()
    
    def get_staff_member(self, user_id):
        self.cursor.execute('SELECT * FROM staff WHERE user_id = ? AND is_active = 1', (user_id,))
        return self.cursor.fetchone()
    
    def get_all_staff(self):
        self.cursor.execute('SELECT * FROM staff WHERE is_active = 1')
        return self.cursor.fetchall()
    
    def get_user_access(self, user_id):
        self.cursor.execute('SELECT access_level FROM users WHERE user_id = ?', (user_id,))
        result = self.cursor.fetchone()
        return result['access_level'] if result else 10
    
    # === متدهای کانال ===
    def add_channel(self, channel_id, channel_name, channel_type, added_by, is_required=False):
        self.cursor.execute('''
            INSERT OR REPLACE INTO channels (channel_id, channel_name, type, added_by, is_required)
            VALUES (?, ?, ?, ?, ?)
        ''', (channel_id, channel_name, channel_type, added_by, is_required))
        self.conn.commit()
    
    def remove_channel(self, channel_id):
        self.cursor.execute('DELETE FROM channels WHERE channel_id = ?', (channel_id,))
        self.conn.commit()
    
    def get_all_channels(self):
        self.cursor.execute('SELECT * FROM channels')
        return self.cursor.fetchall()
    
    def get_required_channels(self):
        self.cursor.execute('SELECT * FROM channels WHERE is_required = 1')
        return self.cursor.fetchall()
    
    # === متدهای مالی ===
    def add_transaction(self, user_id, amount, tx_type, plan=None, receipt_file=None):
        self.cursor.execute('''
            INSERT INTO transactions (user_id, amount, type, plan, receipt_file)
            VALUES (?, ?, ?, ?, ?)
        ''', (user_id, amount, tx_type, plan, receipt_file))
        self.conn.commit()
        return self.cursor.lastrowid
    
    def confirm_transaction(self, tx_id, confirmed_by):
        self.cursor.execute('UPDATE transactions SET status = "confirmed", confirmed_by = ? WHERE id = ?',
                          (confirmed_by, tx_id))
        self.cursor.execute('SELECT user_id, amount, plan FROM transactions WHERE id = ?', (tx_id,))
        tx = self.cursor.fetchone()
        
        if tx:
            user_id, amount, plan = tx
            
            # فعال‌سازی اشتراک
            if plan and plan in PLANS:
                days = PLANS[plan]['days']
                self.add_subscription(user_id, days)
                self.cursor.execute('UPDATE users SET total_purchases = total_purchases + 1 WHERE user_id = ?',
                                  (user_id,))
            
            # پورسانت معرف
            user = self.get_user(user_id)
            if user and user['referral_by']:
                commission = int(amount * COMMISSION_PERCENT / 100)
                self.cursor.execute('''
                    UPDATE users SET referral_earnings = referral_earnings + ? WHERE user_id = ?
                ''', (commission, user['referral_by']))
                
                # آپدیت وضعیت پورسانت
                self.cursor.execute('''
                    UPDATE referrals SET commission_paid = commission_paid + ? 
                    WHERE inviter_id = ? AND invited_id = ?
                ''', (commission, user['referral_by'], user_id))
        
        self.conn.commit()
    
    def add_subscription(self, user_id, days):
        user = self.get_user(user_id)
        if user and user['subscription_until']:
            try:
                start_date = datetime.strptime(user['subscription_until'], '%Y-%m-%d %H:%M:%S')
                if start_date < datetime.now():
                    start_date = datetime.now()
            except:
                start_date = datetime.now()
        else:
            start_date = datetime.now()
        
        end_date = start_date + timedelta(days=days)
        self.cursor.execute('UPDATE users SET subscription_until = ? WHERE user_id = ?',
                          (end_date.strftime('%Y-%m-%d %H:%M:%S'), user_id))
        self.conn.commit()
    
    def get_pending_transactions(self):
        self.cursor.execute('SELECT * FROM transactions WHERE status = "pending" ORDER BY date DESC')
        return self.cursor.fetchall()
    
    def request_withdrawal(self, user_id, amount, card_number):
        self.cursor.execute('''
            INSERT INTO withdrawals (user_id, amount, card_number) VALUES (?, ?, ?)
        ''', (user_id, amount, card_number))
        
        # کم کردن از موجودی
        self.cursor.execute('''
            UPDATE users SET referral_earnings = referral_earnings - ? WHERE user_id = ?
        ''', (amount, user_id))
        
        self.conn.commit()
        return self.cursor.lastrowid
    
    def get_pending_withdrawals(self):
        self.cursor.execute('SELECT * FROM withdrawals WHERE status = "pending"')
        return self.cursor.fetchall()
    
    def confirm_withdrawal(self, withdrawal_id, processed_by):
        self.cursor.execute('''
            UPDATE withdrawals SET status = "confirmed", processed_date = CURRENT_TIMESTAMP, 
            processed_by = ? WHERE id = ?
        ''', (processed_by, withdrawal_id))
        self.conn.commit()
    
    # === متدهای لاگ ===
    def add_log(self, user_id, username, action, details):
        self.cursor.execute('''
            INSERT INTO activity_logs (user_id, username, action, details)
            VALUES (?, ?, ?, ?)
        ''', (user_id, username, action, json.dumps(details, ensure_ascii=False)))
        self.conn.commit()
    
    def get_logs(self, limit=50, action=None):
        query = 'SELECT * FROM activity_logs'
        params = []
        if action:
            query += ' WHERE action = ?'
            params.append(action)
        query += ' ORDER BY timestamp DESC LIMIT ?'
        params.append(limit)
        self.cursor.execute(query, params)
        return self.cursor.fetchall()
    
    # === متدهای آماری ===
    def get_full_stats(self):
        stats = {}
        
        self.cursor.execute('SELECT COUNT(*) as cnt FROM users')
        stats['total_users'] = self.cursor.fetchone()['cnt']
        
        self.cursor.execute('SELECT COUNT(*) as cnt FROM users WHERE access_level >= 50')
        stats['total_admins'] = self.cursor.fetchone()['cnt']
        
        self.cursor.execute('SELECT COUNT(*) as cnt FROM users WHERE is_banned = 1')
        stats['banned_users'] = self.cursor.fetchone()['cnt']
        
        self.cursor.execute('SELECT COUNT(*) as cnt, COALESCE(SUM(amount), 0) as total FROM transactions WHERE status = "confirmed"')
        row = self.cursor.fetchone()
        stats['total_sales'] = row['cnt']
        stats['total_revenue'] = row['total']
        
        self.cursor.execute('SELECT COUNT(*) as cnt, COALESCE(SUM(amount), 0) as total FROM transactions WHERE status = "pending"')
        row = self.cursor.fetchone()
        stats['pending_count'] = row['cnt']
        stats['pending_amount'] = row['total']
        
        self.cursor.execute("SELECT COUNT(*) as cnt FROM users WHERE joined_date >= datetime('now', '-7 days')")
        stats['new_users_week'] = self.cursor.fetchone()['cnt']
        
        self.cursor.execute("SELECT COUNT(*) as cnt, COALESCE(SUM(amount), 0) as total FROM transactions WHERE status = 'confirmed' AND date >= datetime('now', '-7 days')")
        row = self.cursor.fetchone()
        stats['week_sales'] = row['cnt']
        stats['week_revenue'] = row['total']
        
        self.cursor.execute("SELECT COUNT(*) as cnt FROM users WHERE joined_date >= datetime('now', '-30 days')")
        stats['new_users_month'] = self.cursor.fetchone()['cnt']
        
        return stats
    
    # === متدهای مسدودسازی ===
    def ban_user(self, user_id, reason):
        self.cursor.execute('UPDATE users SET is_banned = 1, ban_reason = ? WHERE user_id = ?', (reason, user_id))
        self.conn.commit()
    
    def unban_user(self, user_id):
        self.cursor.execute('UPDATE users SET is_banned = 0, ban_reason = NULL WHERE user_id = ?', (user_id,))
        self.conn.commit()
    
    def get_banned_users(self):
        self.cursor.execute('SELECT * FROM users WHERE is_banned = 1')
        return self.cursor.fetchall()
from telegram import ReplyKeyboardMarkup, InlineKeyboardMarkup, InlineKeyboardButton
from config import PLANS

def main_menu(is_admin=False):
    keyboard = [
        ['🔑 خرید اشتراک', '👤 پروفایل من'],
        ['💰 کیف پول', '🔗 زیرمجموعه‌گیری'],
        ['📊 آمار من', '📞 پشتیبانی']
    ]
    if is_admin:
        keyboard.append(['🎛️ پنل مدیریت'])
    return ReplyKeyboardMarkup(keyboard, resize_keyboard=True)

def admin_panel_keyboard(access_level):
    keyboard = []
    
    keyboard.append([
        InlineKeyboardButton("📊 داشبورد", callback_data="admin_dashboard"),
        InlineKeyboardButton("💰 تراکنش‌ها", callback_data="admin_transactions")
    ])
    keyboard.append([
        InlineKeyboardButton("👥 کاربران", callback_data="admin_users"),
        InlineKeyboardButton("📝 لاگ‌ها", callback_data="admin_logs")
    ])
    keyboard.append([
        InlineKeyboardButton("💳 درخواست‌های برداشت", callback_data="admin_withdrawals"),
        InlineKeyboardButton("🚫 مسدودها", callback_data="admin_banned")
    ])
    
    if access_level >= 80:  # super_admin
        keyboard.append([
            InlineKeyboardButton("👨‍💼 مدیریت ادمین‌ها", callback_data="admin_staff"),
            InlineKeyboardButton("➕ افزودن ادمین", callback_data="admin_add_staff")
        ])
    
    if access_level >= 100:  # owner
        keyboard.append([
            InlineKeyboardButton("📢 کانال‌ها", callback_data="admin_channels"),
            InlineKeyboardButton("⚙️ تنظیمات", callback_data="admin_settings")
        ])
    
    keyboard.append([InlineKeyboardButton("🔙 خروج", callback_data="admin_exit")])
    
    return InlineKeyboardMarkup(keyboard)

def plans_keyboard():
    keyboard = []
    for plan_id, plan in PLANS.items():
        keyboard.append([InlineKeyboardButton(
            f"📦 {plan['name']} - {plan['price']:,} تومان ({plan['traffic']})",
            callback_data=f"buy_{plan_id}"
        )])
    keyboard.append([InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")])
    return InlineKeyboardMarkup(keyboard)

def payment_method_keyboard(plan_id):
    keyboard = [
        [InlineKeyboardButton("💳 کارت به کارت", callback_data=f"pay_card_{plan_id}")],
        [InlineKeyboardButton("🔙 بازگشت", callback_data="plans")]
    ]
    return InlineKeyboardMarkup(keyboard)

def payment_keyboard(plan_id):
    keyboard = [
        [InlineKeyboardButton("📤 ارسال رسید پرداخت", callback_data=f"receipt_{plan_id}")],
        [InlineKeyboardButton("✅ پرداخت کردم", callback_data=f"paid_{plan_id}")],
        [InlineKeyboardButton("🔙 بازگشت", callback_data="plans")]
    ]
    return InlineKeyboardMarkup(keyboard)

def confirm_transaction_keyboard(tx_id):
    keyboard = [
        [
            InlineKeyboardButton("✅ تایید", callback_data=f"confirm_tx_{tx_id}"),
            InlineKeyboardButton("❌ رد", callback_data=f"reject_tx_{tx_id}")
        ],
        [InlineKeyboardButton("🔙 بازگشت", callback_data="admin_transactions")]
    ]
    return InlineKeyboardMarkup(keyboard)

def withdraw_keyboard():
    keyboard = [
        [InlineKeyboardButton("💰 برداشت موجودی", callback_data="withdraw_request")],
        [InlineKeyboardButton("📋 تاریخچه برداشت‌ها", callback_data="withdraw_history")],
        [InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")]
    ]
    return InlineKeyboardMarkup(keyboard)
from telegram import Update
from telegram.ext import ContextTypes, ConversationHandler
from telegram.constants import ParseMode
from datetime import datetime
from database import Database
from config import PLANS, CARD_NUMBER, CARD_HOLDER, OWNER_USERNAME, ACCESS_LEVELS
import keyboards as kb
import os

db = Database()

# Stateهای مکالمه
(RECEIPT_PHOTO, WITHDRAW_AMOUNT, WITHDRAW_CARD,
 ADD_STAFF_ID, ADD_STAFF_NAME, ADD_STAFF_ROLE,
 BAN_USER_ID, BAN_REASON, ADD_CHANNEL_ID, ADD_CHANNEL_NAME) = range(10)

async def start_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
    user = update.effective_user
    referral_by = None
    
    if context.args and context.args[0].startswith('ref_'):
        try:
            referral_by = int(context.args[0].replace('ref_', ''))
        except:
            pass
    
    db.add_user(user.id, user.username or '', user.first_name, referral_by=referral_by)
    
    access_level = db.get_user_access(user.id)
    is_admin = access_level >= ACCESS_LEVELS['admin']
    
    welcome_text = f"""
🎉 **به ربات ریپورتر خوش آمدید!**

👤 کاربر: {user.first_name}
🆔 آیدی: `{user.id}`

🔹 با این ربات می‌توانید:
• اشتراک VPN خریداری کنید
• با زیرمجموعه‌گیری درآمد کسب کنید
• از پنل حرفه‌ای مدیریت استفاده کنید

💰 **پورسانت زیرمجموعه: ۲۰٪**
🎁 **هدیه ثبت‌نام زیرمجموعه: ۵,۰۰۰ تومان**
"""
    
    db.add_log(user.id, user.username, 'start_bot', {'referred_by': referral_by})
    
    await update.message.reply_text(
        welcome_text,
        reply_markup=kb.main_menu(is_admin),
        parse_mode=ParseMode.MARKDOWN
    )

async def menu_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
    text = update.message.text
    user = update.effective_user
    user_id = user.id
    
    if text == '🔑 خرید اشتراک':
        await update.message.reply_text(
            "📦 **پلن‌های اشتراک موجود:**\n\n"
            "برای مشاهده جزئیات و خرید، یک پلن انتخاب کنید:",
            reply_markup=kb.plans_keyboard(),
            parse_mode=ParseMode.MARKDOWN
        )
    
    elif text == '👤 پروفایل من':
        user_data = db.get_user(user_id)
        if user_data:
            sub_until = user_data['subscription_until']
            if sub_until:
                try:
                    sub_date = datetime.strptime(sub_until, '%Y-%m-%d %H:%M:%S')
                    if sub_date > datetime.now():
                        days_left = (sub_date - datetime.now()).days
                        sub_status = f"✅ فعال ({days_left} روز باقی‌مانده)"
                    else:
                        sub_status = "❌ منقضی شده"
                except:
                    sub_status = "⚠️ نامشخص"
            else:
                sub_status = "❌ غیرفعال"
            
            profile_text = f"""
👤 **پروفایل کاربری**

🆔 شناسه: `{user_data['user_id']}`
👤 نام: {user_data['first_name']}
📱 تلفن: {user_data['phone'] or 'ثبت نشده'}

💳 **وضعیت اشتراک:** {sub_status}
📅 تاریخ عضویت: {user_data['joined_date'][:10]}

🔗 **زیرمجموعه‌ها:** {user_data['total_referrals']} نفر
💰 **درآمد زیرمجموعه:** {user_data['referral_earnings']:,} تومان
🛒 **تعداد خرید:** {user_data['total_purchases']}
"""
            await update.message.reply_text(profile_text, parse_mode=ParseMode.MARKDOWN)
    
    elif text == '💰 کیف پول':
        user_data = db.get_user(user_id)
        earnings = user_data['referral_earnings'] if user_data else 0
        
        wallet_text = f"""
💰 **کیف پول شما**

💸 موجودی قابل برداشت: **{earnings:,} تومان**
📊 پورسانت: **۲۰٪** از هر خرید زیرمجموعه
🎁 هدیه ثبت‌نام: **۵,۰۰۰ تومان** به ازای هر زیرمجموعه

💡 برای برداشت موجودی، روی دکمه زیر کلیک کنید:
"""
        await update.message.reply_text(
            wallet_text,
            reply_markup=kb.withdraw_keyboard(),
            parse_mode=ParseMode.MARKDOWN
        )
    
    elif text == '🔗 زیرمجموعه‌گیری':
        bot_username = context.bot.username
        ref_link = f"https://t.me/{bot_username}?start=ref_{user_id}"
        ref_count = db.get_user(user_id)['total_referrals'] if db.get_user(user_id) else 0
        
        ref_text = f"""
🔗 **لینک زیرمجموعه‌گیری شما:**

`{ref_link}`

📊 **آمار زیرمجموعه‌ها:**
👥 تعداد: **{ref_count}** نفر
💰 پورسانت: **۲۰٪** از هر خرید
🎁 هدیه ثبت‌نام: **۵,۰۰۰ تومان**

📱 لینک رو با دوستانت به اشتراک بذار و کسب درآمد کن!
"""
        await update.message.reply_text(ref_text, parse_mode=ParseMode.MARKDOWN)
    
    elif text == '📊 آمار من':
        user_data = db.get_user(user_id)
        if user_data:
            stats_text = f"""
📊 **آمار فعالیت شما**

👥 زیرمجموعه‌ها: {user_data['total_referrals']} نفر
💰 درآمد کل: {user_data['referral_earnings']:,} تومان
🛒 خریدهای شما: {user_data['total_purchases']}
📅 عضو از: {user_data['joined_date'][:10]}

🎯 **پورسانت شما: ۲۰٪**
"""
            await update.message.reply_text(stats_text, parse_mode=ParseMode.MARKDOWN)
    
    elif text == '📞 پشتیبانی':
        support_text = f"""
📞 **ارتباط با پشتیبانی**

👤 ادمین: @{OWNER_USERNAME}
📱 آیدی پشتیبانی: @{OWNER_USERNAME}

⏰ ساعت پاسخگویی: ۹ صبح تا ۱۱ شب

📝 برای پیگیری سریع‌تر، لطفاً:
• آیدی عددی خود را ارسال کنید
• مشکل را کامل توضیح دهید
• در صورت نیاز، اسکرین‌شات ارسال کنید
"""
        await update.message.reply_text(support_text)
    
    elif text == '🎛️ پنل مدیریت':
        access = db.get_user_access(user_id)
        if access >= ACCESS_LEVELS['admin']:
            await update.message.reply_text(
                "🎛️ **پنل مدیریت حرفه‌ای**\n\n"
                "بخش مورد نظر را انتخاب کنید:",
                reply_markup=kb.admin_panel_keyboard(access),
                parse_mode=ParseMode.MARKDOWN
            )
            db.add_log(user_id, user.username, 'open_admin_panel', {})
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import ContextTypes
from telegram.constants import ParseMode
from datetime import datetime
from database import Database
from config import ACCESS_LEVELS
import keyboards as kb

db = Database()

class AdminHandlers:
    @staticmethod
    def check_access(user_id, required_level):
        return db.get_user_access(user_id) >= required_level
    
    @staticmethod
    async def show_dashboard(update: Update, context: ContextTypes.DEFAULT_TYPE):
        query = update.callback_query
        user_id = query.from_user.id
        
        if not AdminHandlers.check_access(user_id, ACCESS_LEVELS['admin']):
            await query.answer("⛔ دسترسی غیرمجاز!", show_alert=True)
            return
        
        stats = db.get_full_stats()
        
        dashboard = f"""
📊 **داشبورد مدیریت**

👥 **کاربران:**
• کل: {stats['total_users']:,}
• ادمین‌ها: {stats['total_admins']}
• مسدود: {stats['banned_users']}
• جدید (هفته): {stats['new_users_week']}

💰 **مالی:**
• درآمد کل: {stats['total_revenue']:,} تومان
• فروش: {stats['total_sales']} عدد
• در انتظار: {stats['pending_amount']:,} تومان ({stats['pending_count']} تراکنش)

📈 **هفته گذشته:**
• فروش: {stats['week_sales']} عدد
• درآمد: {stats['week_revenue']:,} تومان

🕐 بروزرسانی: {datetime.now().strftime('%H:%M:%S')}
"""
        
        keyboard = [
            [InlineKeyboardButton("🔄 بروزرسانی", callback_data="admin_dashboard")],
            [InlineKeyboardButton("🔙 بازگشت", callback_data="admin_back")]
        ]
        
        await query.edit_message_text(
            dashboard,
            reply_markup=InlineKeyboardMarkup(keyboard),
            parse_mode=ParseMode.MARKDOWN
        )
    
    @staticmethod
    async def show_transactions(update: Update, context: ContextTypes.DEFAULT_TYPE):
        query = update.callback_query
        user_id = query.from_user.id
        
        if not AdminHandlers.check_access(user_id, ACCESS_LEVELS['admin']):
            await query.answer("⛔ دسترسی غیرمجاز!", show_alert=True)
            return
        
        pending = db.get_pending_transactions()
        
        if not pending:
            await query.edit_message_text(
                "📭 تراکنش در انتظاری وجود ندارد.",
                reply_markup=InlineKeyboardMarkup([[
                    InlineKeyboardButton("🔙 بازگشت", callback_data="admin_back")
                ]])
            )
            return
        
        for tx in pending[:5]:
            user = db.get_user(tx['user_id'])
            plan_name = PLANS.get(tx['plan'], {}).get('name', 'نامشخص') if tx['plan'] else 'نامشخص'
            
            tx_text = f"""
🔄 **تراکنش #{tx['id']}**

👤 کاربر: {user['first_name'] if user else 'نامشخص'} (@{user['username'] if user else 'نامشخص'})
💰 مبلغ: {tx['amount']:,} تومان
📦 پلن: {plan_name}
📅 تاریخ: {tx['date']}
📎 رسید: {'دارد ✅' if tx['receipt_file'] else 'ندارد ❌'}
"""
            
            await query.message.reply_text(
                tx_text,
                reply_markup=kb.confirm_transaction_keyboard(tx['id']),
                parse_mode=ParseMode.MARKDOWN
            )
        
        await query.edit_message_text(
            f"📋 **{len(pending)} تراکنش در انتظار**\n\n"
            "برای مشاهده جزئیات به پیام‌های بالا مراجعه کنید.",
            reply_markup=InlineKeyboardMarkup([[
                InlineKeyboardButton("🔙 بازگشت", callback_data="admin_back")
            ]])
        )
    
    @staticmethod
    async def manage_staff(update: Update, context: ContextTypes.DEFAULT_TYPE):
        query = update.callback_query
        user_id = query.from_user.id
        
        if not AdminHandlers.check_access(user_id, ACCESS_LEVELS['super_admin']):
            await query.answer("⛔ دسترسی غیرمجاز!", show_alert=True)
            return
        
        staff_list = db.get_all_staff()
        
        text = "👨‍💼 **لیست پرسنل:**\n\n"
        keyboard = []
        
        for staff in staff_list:
            role_emoji = {'owner': '👑', 'super_admin': '⭐', 'admin': '🛡️', 'moderator': '👁️'}.get(staff['role'], '👤')
            
            text += f"{role_emoji} {staff['full_name']} (@{staff['username']})\n"
            text += f"   نقش: {staff['role']} | سطح: {staff['access_level']}\n\n"
            
            if user_id != staff['user_id']:  # نمی‌تونی خودت رو حذف کنی
                keyboard.append([
                    InlineKeyboardButton(f"❌ حذف {staff['full_name']}", callback_data=f"remove_staff_{staff['user_id']}")
                ])
        
        keyboard.append([InlineKeyboardButton("➕ افزودن ادمین", callback_data="admin_add_staff")])
        keyboard.append([InlineKeyboardButton("🔙 بازگشت", callback_data="admin_back")])
        
        await query.edit_message_text(
            text,
            reply_markup=InlineKeyboardMarkup(keyboard),
            parse_mode=ParseMode.MARKDOWN
        )
    
    @staticmethod
    async def show_logs(update: Update, context: ContextTypes.DEFAULT_TYPE):
        query = update.callback_query
        user_id = query.from_user.id
        
        if not AdminHandlers.check_access(user_id, ACCESS_LEVELS['admin']):
            await query.answer("⛔ دسترسی غیرمجاز!", show_alert=True)
            return
        
        logs = db.get_logs(limit=20)
        
        text = "📝 **آخرین فعالیت‌ها:**\n\n"
        for log in logs:
            text += f"🕐 {log['timestamp'][11:19]} | 👤 @{log['username']}\n"
            text += f"   {log['action']}\n\n"
        
        keyboard = [
            [InlineKeyboardButton("🔄 بروزرسانی", callback_data="admin_logs")],
            [InlineKeyboardButton("🔙 بازگشت", callback_data="admin_back")]
        ]
        
        await query.edit_message_text(
            text[:4000],
            reply_markup=InlineKeyboardMarkup(keyboard),
            parse_mode=ParseMode.MARKDOWN
        )
    
    @staticmethod
    async def show_withdrawals(update: Update, context: ContextTypes.DEFAULT_TYPE):
        query = update.callback_query
        user_id = query.from_user.id
        
        if not AdminHandlers.check_access(user_id, ACCESS_LEVELS['admin']):
            await query.answer("⛔ دسترسی غیرمجاز!", show_alert=True)
            return
        
        withdrawals = db.get_pending_withdrawals()
        
        if not withdrawals:
            await query.edit_message_text(
                "📭 درخواست برداشت در انتظاری وجود ندارد.",
                reply_markup=InlineKeyboardMarkup([[
                    InlineKeyboardButton("🔙 بازگشت", callback_data="admin_back")
                ]])
            )
            return
        
        for w in withdrawals:
            user = db.get_user(w['user_id'])
            text = f"""
💳 **درخواست برداشت #{w['id']}**

👤 کاربر: {user['first_name'] if user else 'نامشخص'}
💰 مبلغ: {w['amount']:,} تومان
🏦 شماره کارت: `{w['card_number']}`
📅 تاریخ: {w['request_date']}
"""
            
            keyboard = [[
                InlineKeyboardButton("✅ پرداخت شد", callback_data=f"confirm_withdraw_{w['id']}"),
                InlineKeyboardButton("❌ رد", callback_data=f"reject_withdraw_{w['id']}")
            ]]
            
            await query.message.reply_text(
                text,
                reply_markup=InlineKeyboardMarkup(keyboard),
                parse_mode=ParseMode.MARKDOWN
            )
from telegram import Update
from telegram.ext import ContextTypes
from telegram.constants import ParseMode
from database import Database
from config import PLANS, CARD_NUMBER, CARD_HOLDER, ACCESS_LEVELS
from admin_handler import AdminHandlers
import keyboards as kb
import os

db = Database()

async def button_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query
    await query.answer()
    
    data = query.data
    user_id = query.from_user.id
    user = query.from_user
    
    # === کال‌بک‌های خرید ===
    if data.startswith('buy_'):
        plan_id = data.replace('buy_', '')
        plan = PLANS.get(plan_id)
        if plan:
            await query.edit_message_text(
                f"📦 **{plan['name']}**\n\n"
                f"💰 قیمت: {plan['price']:,} تومان\n"
                f"📊 حجم: {plan['traffic']}\n"
                f"📅 مدت: {plan['days']} روز\n\n"
                f"روش پرداخت را انتخاب کنید:",
                reply_markup=kb.payment_method_keyboard(plan_id),
                parse_mode=ParseMode.MARKDOWN
            )
    
    elif data.startswith('pay_card_'):
        plan_id = data.replace('pay_card_', '')
        plan = PLANS.get(plan_id)
        if plan:
            await query.edit_message_text(
                f"💳 **پرداخت کارت به کارت**\n\n"
                f"📦 پلن: {plan['name']}\n"
                f"💰 مبلغ: {plan['price']:,} تومان\n\n"
                f"🏦 **شماره کارت:**\n"
                f"`{CARD_NUMBER}`\n"
                f"👤 **به نام:** {CARD_HOLDER}\n\n"
                f"⚠️ پس از پرداخت، روی دکمه زیر کلیک کنید\n"
                f"و رسید پرداخت را ارسال نمایید:",
                reply_markup=kb.payment_keyboard(plan_id),
                parse_mode=ParseMode.MARKDOWN
            )
    
    elif data.startswith('receipt_'):
        plan_id = data.replace('receipt_', '')
        context.user_data['buying_plan'] = plan_id
        await query.edit_message_text(
            "📤 لطفاً تصویر رسید پرداخت را ارسال کنید:",
            parse_mode=ParseMode.MARKDOWN
        )
        return RECEIPT_PHOTO
    
    elif data.startswith('paid_'):
        plan_id = data.replace('paid_', '')
        plan = PLANS.get(plan_id)
        if plan:
            tx_id = db.add_transaction(user_id, plan['price'], 'purchase', plan_id)
            db.add_log(user_id, user.username, 'new_transaction', {'tx_id': tx_id, 'plan': plan_id, 'amount': plan['price']})
            
            await query.edit_message_text(
                f"✅ **درخواست شما ثبت شد**\n\n"
                f"🔢 شماره پیگیری: `{tx_id}`\n"
                f"💰 مبلغ: {plan['price']:,} تومان\n"
                f"📦 پلن: {plan['name']}\n\n"
                f"⏳ پس از تایید ادمین، اشتراک شما فعال می‌شود.\n"
                f"📞 در صورت تاخیر با پشتیبانی تماس بگیرید.",
                reply_markup=InlineKeyboardMarkup([[
                    InlineKeyboardButton("🔙 بازگشت به منو", callback_data="back_main")
                ]]),
                parse_mode=ParseMode.MARKDOWN
            )
    
    # === کال‌بک‌های پنل مدیریت ===
    elif data == "admin_dashboard":
        await AdminHandlers.show_dashboard(update, context)
    
    elif data == "admin_transactions":
        await AdminHandlers.show_transactions(update, context)
    
    elif data == "admin_staff":
        await AdminHandlers.manage_staff(update, context)
    
    elif data == "admin_logs":
        await AdminHandlers.show_logs(update, context)
    
    elif data == "admin_withdrawals":
        await AdminHandlers.show_withdrawals(update, context)
    
    elif data == "admin_back":
        access = db.get_user_access(user_id)
        await query.edit_message_text(
            "🎛️ **پنل مدیریت**",
            reply_markup=kb.admin_panel_keyboard(access),
            parse_mode=ParseMode.MARKDOWN
        )
    
    elif data == "admin_exit":
        await query.edit_message_text("✅ از پنل مدیریت خارج شدید.")
    
    # === تایید/رد تراکنش ===
    elif data.startswith('confirm_tx_'):
        tx_id = int(data.replace('confirm_tx_', ''))
        if AdminHandlers.check_access(user_id, ACCESS_LEVELS['admin']):
            db.confirm_transaction(tx_id, user_id)
            db.add_log(user_id, user.username, 'confirm_transaction', {'tx_id': tx_id})
            await query.edit_message_text(
                f"✅ تراکنش #{tx_id} با موفقیت تایید شد.",
                reply_markup=InlineKeyboardMarkup([[
                    InlineKeyboardButton("🔙 بازگشت", callback_data="admin_transactions")
                ]])
            )
    
    elif data.startswith('reject_tx_'):
        tx_id = int(data.replace('reject_tx_', ''))
        if AdminHandlers.check_access(user_id, ACCESS_LEVELS['admin']):
            db.cursor.execute('UPDATE transactions SET status = "rejected" WHERE id = ?', (tx_id,))
            db.conn.commit()
            db.add_log(user_id, user.username, 'reject_transaction', {'tx_id': tx_id})
            await query.edit_message_text(
                f"❌ تراکنش #{tx_id} رد شد.",
                reply_markup=InlineKeyboardMarkup([[
                    InlineKeyboardButton("🔙 بازگشت", callback_data="admin_transactions")
                ]])
            )
    
    # === تایید برداشت ===
    elif data.startswith('confirm_withdraw_'):
        w_id = int(data.replace('confirm_withdraw_', ''))
        if AdminHandlers.check_access(user_id, ACCESS_LEVELS['admin']):
            db.confirm_withdrawal(w_id, user_id)
            db.add_log(user_id, user.username, 'confirm_withdrawal', {'withdrawal_id': w_id})
            await query.edit_message_text(
                f"✅ برداشت #{w_id} تایید و پرداخت شد.",
                reply_markup=InlineKeyboardMarkup([[
                    InlineKeyboardButton("🔙 بازگشت", callback_data="admin_withdrawals")
                ]])
            )
    
    # === برداشت کاربر ===
    elif data == "withdraw_request":
        await query.edit_message_text(
            "💳 لطفاً مبلغ مورد نظر برای برداشت را وارد کنید (تومان):\n\n"
            f"⚠️ حداقل برداشت: ۱۰۰,۰۰۰ تومان",
            parse_mode=ParseMode.MARKDOWN
        )
        return WITHDRAW_AMOUNT
    
    # === بازگشت‌ها ===
    elif data == "plans":
        await query.edit_message_text(
            "📦 **پلن‌های اشتراک:**",
            reply_markup=kb.plans_keyboard(),
            parse_mode=ParseMode.MARKDOWN
        )
    
    elif data == "back_main":
        await query.edit_message_text(
            "🏠 به منوی اصلی بازگشتید.\n"
            "برای ادامه از کیبورد زیر استفاده کنید:"
        )
import logging
from telegram import Update
from telegram.ext import Application, CommandHandler, MessageHandler, CallbackQueryHandler, ConversationHandler, filters
from config import BOT_TOKEN, RECEIPT_PHOTO, WITHDRAW_AMOUNT, WITHDRAW_CARD
from handlers import start_command, menu_handler
from callbacks import button_callback
from database import Database

# تنظیم لاگ
logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    level=logging.INFO
)
logger = logging.getLogger(__name__)

db = Database()

async def handle_receipt(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """هندلر دریافت عکس رسید"""
    user_id = update.effective_user.id
    plan_id = context.user_data.get('buying_plan')
    
    if plan_id and update.message.photo:
        from config import PLANS
        plan = PLANS.get(plan_id)
        if plan:
            # ذخیره عکس
            photo_file = await update.message.photo[-1].get_file()
            file_path = f"receipts/{user_id}_{plan_id}_{update.message.message_id}.jpg"
            os.makedirs('receipts', exist_ok=True)
            await photo_file.download_to_drive(file_path)
            
            # ثبت تراکنش
            tx_id = db.add_transaction(user_id, plan['price'], 'purchase', plan_id, file_path)
            db.add_log(user_id, update.effective_user.username, 'new_transaction_with_receipt', 
                      {'tx_id': tx_id, 'plan': plan_id})
            
            await update.message.reply_text(
                f"✅ رسید پرداخت دریافت شد\n\n"
                f"🔢 شماره پیگیری: `{tx_id}`\n"
                f"💰 مبلغ: {plan['price']:,} تومان\n\n"
                f"⏳ در حال بررسی و تایید..."
            )
    
    return ConversationHandler.END

async def handle_withdraw_amount(update: Update, context: ContextTypes.DEFAULT_TYPE):
    try:
        amount = int(update.message.text)
        if amount < 100000:
            await update.message.reply_text("❌ حداقل مبلغ برداشت ۱۰۰,۰۰۰ تومان است.")
            return WITHDRAW_AMOUNT
        
        context.user_data['withdraw_amount'] = amount
        await update.message.reply_text(
            "💳 لطفاً شماره کارت ۱۶ رقمی خود را وارد کنید:\n\n"
            "⚠️ دقت کنید شماره کارت صحیح باشد."
        )
        return WITHDRAW_CARD
    except ValueError:
        await update.message.reply_text("❌ لطفاً مبلغ را به عدد وارد کنید.")
        return WITHDRAW_AMOUNT

async def handle_withdraw_card(update: Update, context: ContextTypes.DEFAULT_TYPE):
    card_number = update.message.text.strip()
    amount = context.user_data.get('withdraw_amount')
    user_id = update.effective_user.id
    
    if len(card_number) < 16:
        await update.message.reply_text("❌ شماره کارت نامعتبر است. دوباره وارد کنید:")
        return WITHDRAW_CARD
    
    # ثبت درخواست برداشت
    user_data = db.get_user(user_id)
    if user_data and user_data['referral_earnings'] >= amount:
        w_id = db.request_withdrawal(user_id, amount, card_number)
        db.add_log(user_id, update.effective_user.username, 'withdraw_request', 
                  {'amount': amount, 'card': card_number})
        
        await update.message.reply_text(
            f"✅ درخواست برداشت ثبت شد\n\n"
            f"🔢 شماره پیگیری: `{w_id}`\n"
            f"💰 مبلغ: {amount:,} تومان\n"
            f"💳 کارت: {card_number[:4]}-****-****-{card_number[-4:]}\n\n"
            f"⏳ طی ۲۴ ساعت آینده پرداخت می‌شود."
        )
    else:
        await update.message.reply_text("❌ موجودی کافی نیست!")
    
    return ConversationHandler.END

def main():
    # ساخت اپلیکیشن
    application = Application.builder().token(BOT_TOKEN).build()
    
    # ConversationHandler برای برداشت
    withdraw_conv = ConversationHandler(
        entry_points=[CallbackQueryHandler(button_callback, pattern="withdraw_request")],
        states={
            WITHDRAW_AMOUNT: [MessageHandler(filters.TEXT & ~filters.COMMAND, handle_withdraw_amount)],
            WITHDRAW_CARD: [MessageHandler(filters.TEXT & ~filters.COMMAND, handle_withdraw_card)],
        },
        fallbacks=[CallbackQueryHandler(button_callback, pattern="back_main")]
    )
    
    # ConversationHandler برای رسید
    receipt_conv = ConversationHandler(
        entry_points=[CallbackQueryHandler(button_callback, pattern="receipt_")],
        states={
            RECEIPT_PHOTO: [MessageHandler(filters.PHOTO, handle_receipt)],
        },
        fallbacks=[CallbackQueryHandler(button_callback, pattern="back_main")]
    )
    
    # اضافه کردن هندلرها
    application.add_handler(CommandHandler("start", start_command))
    application.add_handler(withdraw_conv)
    application.add_handler(receipt_conv)
    application.add_handler(CallbackQueryHandler(button_callback))
    application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, menu_handler))
    
    # شروع ربات
    print("🤖 ربات ریپورتر با موفقیت راه‌اندازی شد!")
    print("=" * 50)
    application.run_polling(all_updates=True)

if __name__ == '__main__':
    main()
